package com.fortune.cat.manager;

import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhaozeyang
 * @date 2019/4/18 15:15
 * @description 关于 GatewayFilter的额外管理
 */
public class GatewayFilterManager {

    private final Map<String, GatewayFilterFactory> gatewayFilterFactories = new ConcurrentHashMap<>();

    private final Map<String, ExternalGatewayFilterFactoryInfo> externalGatewayFilterFactory = new ConcurrentHashMap<>();

    public GatewayFilterManager(List<GatewayFilterFactory> gatewayFilterFactories) {
        gatewayFilterFactories.forEach(
                factory -> this.gatewayFilterFactories.put(factory.name(), factory));
        registerFilterName();
    }

    public void addFilterFactories(List<ExternalGatewayFilterFactoryInfo> factoryInfos) {
        factoryInfos.forEach(factoryInfo -> externalGatewayFilterFactory.put(factoryInfo.factory.name(), factoryInfo));
        registerFilterName();
    }

    public void registerFilterName() {
        //todo 将filter的name注册到ZooKeeper
    }


    /**
     * 获取所有GatewayFilterFactory信息，此处将原生GatewayFilterFactory和groovy的GatewayFilterFactory进行整合
     *
     * @return
     */
    public Map<String, GatewayFilterFactory> getGatewayFilterFactories() {
        Map<String, GatewayFilterFactory> result = new HashMap<>(16);
        result.putAll(gatewayFilterFactories);
        externalGatewayFilterFactory.forEach((s, externalGatewayFilterFactoryInfo) -> result.put(s, externalGatewayFilterFactoryInfo.factory));
        return result;
    }

    /**
     * 清楚外部加载的filter
     */
    public List<String> clearExternalFilterFactories() {
        List<String> result = Lists.newArrayList();
        externalGatewayFilterFactory.values().forEach(p -> {
            result.add(p.getBeanName());
        });
        externalGatewayFilterFactory.clear();
        registerFilterName();
        return result;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ExternalGatewayFilterFactoryInfo {

        private String beanName;

        private GatewayFilterFactory factory;
    }

}
